#!/usr/bin/python

import pygst
pygst.require("0.10")
import gst

class StreamManager:
	"Classe do gerenciador de media.\nFornece funcoes de abrir, tocar e pausa."

	def __init__(self, metadata_callback=None, eos_callback=None):
		'''Construtor do StreamManager. Pode receber uma funcao de atualizacao a
ser chamada quando houver mudanca nos metadados.'''
		self.title = None
		self.artist = None
		self.position = gst.CLOCK_TIME_NONE
		self.duration = gst.CLOCK_TIME_NONE
		self.metadata_callback = metadata_callback
		self.eos_callback = eos_callback
		
		self.player = gst.element_factory_make("playbin", "playaPlaybin")

		bus = self.player.get_bus()
		bus.add_signal_watch()
		bus.connect('message', self.__on_message)

	def __on_message(self, bus, message):
		"Recebe mensagens da Bus."
		if message.type == gst.MESSAGE_TAG:
			tags = message.parse_tag()
			try:
				self.title = tags['title']
				self.artist = tags['artist']
			except:
				pass
			if self.metadata_callback:
				self.metadata_callback()
		elif message.type == gst.MESSAGE_EOS:
			if self.eos_callback:
				self.eos_callback()
		elif message.type == gst.MESSAGE_ERROR:
			print 'ERROR'
			print message

	def is_playing(self):
		print 'is_playing:'
		print self.player.get_state()[1]
		print self.player.get_state()[1] == gst.STATE_PLAYING
		playing = self.player.get_state()[1] == gst.STATE_PLAYING
		return playing

	def open(self, filepath):
		"Abre arquivo de audio (na verdade de midia, mas vamos ficar no audio)."
		self.player.set_property('uri', 'file://' + filepath)
		self.player.set_state(gst.STATE_READY)
		self.title = filepath
		self.artist = None
		self.duration = 0

	def play(self):
		"Toca o stream de audio carregado."
		return \
			self.player.set_state(gst.STATE_PLAYING) == gst.STATE_CHANGE_SUCCESS

	def pause(self):
		"Pausa o stream de audio carregado."
		return \
			self.player.set_state(gst.STATE_PAUSED) == gst.STATE_CHANGE_SUCCESS
		
	def seek(self, location):
		"Move para localizacao temporal dentro do stream."
		event = gst.event_new_seek(1.0, gst.FORMAT_TIME,
				gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
				gst.SEEK_TYPE_SET, location, gst.SEEK_TYPE_NONE, 0)
		success = self.player.send_event(event)
		if not success:
			gst.error("seek to %r failed" % location)
			
		'''Codigo deprecated, esta aqui por um tempo pra servir de referencia
		if res:
			gst.info("setting new stream time to 0")
			self.player.set_new_stream_time(0L)
		else:
			gst.error("seek to %r failed" % location)
		'''

	def get_position(self):
		"Retorna uma tupla (position, duration)"
		try:
			self.position, format = self.player.query_position(gst.FORMAT_TIME)
		except:
			self.position = gst.CLOCK_TIME_NONE
		try:
			self.duration, format = self.player.query_duration(gst.FORMAT_TIME)
		except:
			self.duration = gst.CLOCK_TIME_NONE
			
		return (self.position, self.duration)

	def format_time(self, time):
		time_seconds = time / gst.SECOND
		time_f = '%02d:%02d' % (time_seconds / 60, time_seconds % 60)

		return time_f
